#ifndef __QAHCONTAINER_H__
#define __QAHCONTAINER_H__

#include "qaholom.h"
#include "qahcontrols.h"

using namespace std;

/////////////////////////////////////////////////////////////////////////////////////////
// QahContainer's and its subclasses declaration

class QahContainer : public QahWidget 
{
protected:
   

public: // operations
   QahWidget& containee(int index) 
   {
      GList *list, *ptr;
      
      list = gtk_container_get_children(GTK_CONTAINER(egoWidget));
      ptr  = g_list_nth(list, index);
      //g_print("list ok %08x : %08x, %d\n",ptr, ptr->data, g_list_length(list));
         
      return *((QahWidget*) ptr->data);
   }
   
public: // property members & operations
   void __init_properties() 
   {
      QahWidget::__init_properties();
   }
   
   
};

///////////////////////////////////////////////////////////////////////////////////////
class QahBox : public QahContainer
{
public:  //property members
   QahProperty<gboolean>  homogeneous;
   QahProperty<int>       spacing;

   void __init_properties() 
   {
      QahContainer::__init_properties();
      
      PROPERTY_INIT(homogeneous, "homogeneous");
      PROPERTY_INIT(spacing,     "spacing");
   }


public: 
   QahBox() 
   {
      __init_properties();
   }
    
   QahWidget& contain(QahWidget& containee) 
   {
      gtk_box_pack_start_defaults(GTK_BOX(egoWidget), GTK_WIDGET(containee.egoWidget));
      return containee;
   }

   QahWidget& contain(QahWidget& containee1, QahWidget& containee2) 
   {
      gtk_box_pack_start_defaults(GTK_BOX(egoWidget), GTK_WIDGET(containee1.egoWidget));
      contain(containee2);
      return containee1;
   }

   QahWidget& contain(QahWidget& containee1, QahWidget& containee2, QahWidget& containee3) 
   {
      gtk_box_pack_start_defaults(GTK_BOX(egoWidget), GTK_WIDGET(containee1.egoWidget));
      contain(containee2, containee3);
      return containee1;
   }

   QahWidget& contain(QahWidget& containee1,QahWidget& containee2,QahWidget& containee3,QahWidget& containee4) 
   {
      gtk_box_pack_start_defaults(GTK_BOX(egoWidget), GTK_WIDGET(containee1.egoWidget));
      contain(containee2, containee3, containee4);
      return containee1;
   }

   QahWidget& contain(QahWidget& containee1,QahWidget& containee2,QahWidget& containee3,QahWidget& containee4,
                      QahWidget& containee5) 
   {
      gtk_box_pack_start_defaults(GTK_BOX(egoWidget), GTK_WIDGET(containee1.egoWidget));
      contain(containee2, containee3, containee4, containee5);
      return containee1;
   }
      
   QahWidget& contain(QahWidget& containee, bool expand, bool fill, int padding) 
   {
      // expand      if true, the container divides its free space among the widgets
      // fill        if true, the widget grows to cover the free space
      // padding     the pixel count of free space to keep on each side of the widget
      
      gtk_box_pack_start(GTK_BOX(egoWidget), GTK_WIDGET(containee.egoWidget), expand, fill, padding);
      return containee;
   }
};

class QahHBox : public QahBox
{
public: // property members & operations

public:
   QahHBox()
   {
      egoWidget = gtk_hbox_new(TRUE, 1);
      QahBox::__init_properties();
   }
};

class QahVBox : public QahBox
{
public:
   QahVBox()
   {
      egoWidget = gtk_vbox_new(TRUE, 1);
      QahBox::__init_properties();
   }
};

class QahNotebook : public QahContainer
{
public: // property members & operations
   QahProperty<int>   page;

   void __init_properties() 
   {
      page.init(egoWidget, "page");
   }
   
public:
   QahNotebook() 
   {
      egoWidget = gtk_notebook_new();
      
      QahContainer::__init_properties();
      QahNotebook::__init_properties();
   }
   
   QahWidget& contain(const char* title, QahWidget& content) 
   {
      QahLabel label(title);
      
      gtk_notebook_append_page(GTK_NOTEBOOK(egoWidget), content.egoWidget, label.egoWidget);
      return content;
   }
};



class QahPaned : public QahContainer
{
public: // property members & operations
   QahProperty<int>   maxPosition;
   QahProperty<int>   minPosition;
   QahProperty<int>   position;
   QahProperty<bool>  positionSet;

   void __init_properties() 
   {
      PROPERTY_INIT(maxPosition , "max-position");
      PROPERTY_INIT(minPosition , "min-position");
      PROPERTY_INIT(position    , "position");
      PROPERTY_INIT(positionSet , "position-set");
   }

public:
   QahPaned()
   {
      QahPaned::__init_properties();
   }

   QahWidget& contain(int pos, QahWidget& containee)
   {
      switch (pos)
      {
         case 1:   gtk_paned_add1(GTK_PANED(egoWidget), GTK_WIDGET(containee.egoWidget)); break;
         case 2:   gtk_paned_add2(GTK_PANED(egoWidget), GTK_WIDGET(containee.egoWidget)); break;
         default:  break;
      }

      return containee;
   }

   QahWidget& contain(int pos, QahWidget& containee, bool resize, bool shrink)
   {
      switch (pos)
      {
         case 1:
            gtk_paned_pack1(GTK_PANED(egoWidget),
                            GTK_WIDGET(containee.egoWidget),
                            resize,
                            shrink);
            break;
         case 2:
            gtk_paned_pack2(GTK_PANED(egoWidget),
                            GTK_WIDGET(containee.egoWidget),
                            resize,
                            shrink);
            break;
         default:
            break;
      }

      return containee;
   }
};

class QahVPaned : public QahPaned 
{
public:
   void __init_properties() {}

public:
   QahVPaned() 
   {
      egoWidget = gtk_vpaned_new();
      
      QahVPaned::__init_properties();
   }
};

class QahHPaned : public QahPaned 
{
public:
   void __init_properties() {}
public:
   QahHPaned() 
   {
      egoWidget = gtk_hpaned_new();
      QahHPaned::__init_properties();
   }
};

/////////////////////////////////////////////////////////////////////////////////////////
// QahWindow class declaration

class QahWindow : public QahContainer 
{
protected:
   void __init_properties() 
   {
      QahContainer::__init_properties();
      
      PROPERTY_INIT(title,    "title");
      PROPERTY_INIT(height,   "default-height");
      PROPERTY_INIT(width,    "default-width");
      PROPERTY_INIT(position, "window-position");
   }

public: // window properties
   QahProperty<char*>    title;
   QahProperty<int>      height;
   QahProperty<int>      width;
   QahProperty<int>      position;   

public:
   QahWindow()
   {
      egoWidget = (GtkWidget*) gtk_window_new (GTK_WINDOW_TOPLEVEL);
      
      __init_properties();
   }

public:  // property operations
   void setDefaultSize(int width, int height) 
   { 
      gtk_window_set_default_size (GTK_WINDOW (egoWidget), width, height); 
   }
   
   void setTitle(const char* title) 
   { 
      gtk_window_set_title (GTK_WINDOW (egoWidget), title); 
   }
   
   void setPosition(GtkWindowPosition position) 
   {
      gtk_window_set_position(GTK_WINDOW(egoWidget), position);
   }
   
public: // windows operations
   void showAll() 
   {
      gtk_widget_show_all (GTK_WIDGET(egoWidget)); 
   }
   
   QahWidget& contain(QahWidget& containee) 
   {
      gtk_container_add (GTK_CONTAINER (egoWidget), containee.egoWidget);
      return containee;
   }

public: // window siganl handlers
   // Event Handlers
   // -- QahWindow 會處理（或會被覆寫可能）的訊息處理函式
   // virtual void onCommand(QahControl*); // 接收控制項(menu, control, button ...)傳來之訊息
   // void onActivated();                  // 當視窗被活化時(此時視窗尚未顯示）
   // virtual gint onClosed();             // 當視窗被關閉      "delete-event"
   // virtual void onDestroy();            // 當視窗被摧毀      "destroy-event"
   //void onToolBarAdded();      // 當工具列(ButtonBar, MenuBar, StatusBar ...)被加入
   //void onToolBarRemoved();    // 當工具列被移除
   //void onCursorChanged();     // 當游標被改變
   //void onDeactivated();       // 當視窗被去活化(此時視窗已失去 z-order 最優先）
   //void onDockChanged();       // 工具列有被改變位置
   //void onDragDrop();          // 當有一個拖放動作完成（移入，移動，並放開左鍵）
   //void onDragEnter();         // 有一個拖放動作進入
   //void onDragLeave();         // 有一個拖放動作離開
   //void onDragOver();          // 有一個拖放動作執行中
   //void onFontChanged();       // 當字型被改變
   //void onGetFocus();          // 視窗取得游標焦點(此時視窗已更新完畢)   "focus-in-event"
   //void onLostFocus();         // 當視窗失去焦點（此時視窗  z-order 仍為最高) "focus-out-event"
   //void onPostionChanged();    // 視窗所在位置改變
};

/////////////////////////////////////////////////////////////////////////////////////////
// QahApplication class declaration

class QahApplication 
{
public:
   int init(int argc, char* argv[])
   {
      gtk_init(&argc, &argv);
      return 0;
   }
   
   int run() 
   {
      gtk_main();
      return 0;
   }
};

/////////////////////////////////////////////////////////////////////////////////////////
// QahDrawArea class declaration

class QahDrawArea : public QahWidget 
{
protected:
  void __init_properties() 
   {
      number = 200;
      QahWidget::__init_properties();
   }

public:
   int number;
   
public:
   QahDrawArea() 
   {
      egoWidget = (GtkWidget*) gtk_drawing_area_new(); 
      
      __init_properties(); 
   }
   
   QahDrawArea(int width, int height) 
   {
      egoWidget = (GtkWidget*) gtk_drawing_area_new();
      gtk_widget_set_size_request(egoWidget, width, height);
      
      __init_properties();
   }
   
   
public:
   void requestSize(int width, int height) 
   {
      gtk_widget_set_size_request(egoWidget, width, height);
   }
   
public:
   virtual gboolean onButtonPressed(GdkEventButton* event) { return true; }
   virtual gboolean onMouseMoved(GdkEventButton *event) { return true; }
   virtual gboolean onKeyPressed(GdkEventKey  *event) { return true; }
   virtual gboolean onExpose(GdkEventExpose* event) { return true; }   
};



/////////////////////////////////////////////////////////////////////////////////////////
//

/////////////////////////////////////////////////////////////////////////////////////////
//

/////////////////////////////////////////////////////////////////////////////////////////
//

/////////////////////////////////////////////////////////////////////////////////////////
//


#endif

